<?php

/*
 * Canvas类
 * 模拟一块画布,
 * 用这个对象时,会初始化一块宽20高10的画布
 * 画布可以进行绘制
 * 画布可以绘制一个矩形
 * 
 */

namespace IMooc;

class Canvas {

    public $data;
    //用来保存动态添加的装饰器的属性,测试原型模式时可关闭
    protected $_decorators = array();

    function init($width = 20, $height = 10)
    {
        $data = array();
        for ($i = 0; $i < $height; $i++)
        {
            for ($j = 0; $j < $width; $j++)
            {
                $data[$i][$j] = '*';
            }
        }
        $this->data = $data;
    }

    //动态添加装饰器对象,测试原型模式时可关闭该方法
    function addDecorator(DrawDecorator $decorator)
    {
        $this->_decorators[] = $decorator;
    }

    //添加调用装饰器的方法,测试原型模式时可关闭
    function beforeDraw()
    {
        //beforeDraw,在事件发生前,按顺序,先进先出
        foreach ($this->_decorators as $decorator)
        {
            $decorator->beforeDraw();
        }
    }

    //添加调用装饰器的方法,测试原型模式时可关闭
    function afterDraw()
    {
        //afterDraw,在事件发生后,按顺序,后进先出,所以得进行反转
        $decorators = array_reverse($this->_decorators);
        foreach ($decorators as $decorator)
        {
            $decorator->afterDraw();
        }
    }

    function draw()
    {
        //添加装饰器,在调用draw方法前调用,测试原型模式时可关闭该方法
        $this->beforeDraw();
        foreach ($this->data as $line)
        {
            foreach ($line as $char)
            {
                echo $char;
            }
            echo '<br />';
        }
        //添加装饰器,在调用draw方法后调用,测试原型模式时可关闭该方法
        $this->afterDraw();
    }

    function rect($a1, $a2, $b1, $b2)
    {
        foreach ($this->data as $k1 => $line)
        {
            if ($k1 < $a1 or $k1 > $a2)
            {
                continue;
            }
            foreach ($line as $k2 => $char)
            {
                if ($k2 < $b1 or $k2 > $b2)
                {
                    continue;
                }
                $this->data[$k1][$k2] = '&nbsp;';
            }
        }
    }

}
